(ns test.amsi.test
  (:use clojure.test)
  (:require [amsi.common.worker :as worker])
  (:require [amsi.common.logging :as logger])
  (:require [amsi.offer.offer :as offer]))

(defn is-coll-size
  [size coll]
  "tests collection size"
  (is (= size (count coll))))

(defn is-offer-min
  [new-min offers]
  "tests new unique min"
  (let[
       min-offer (reduce offer/min-offer offers)]
    (is(= new-min (:offer (val min-offer))))))

(defn is-offer-counter
  [value key-value offers]
  "tests offer counter"
  (is(= value (get offers key-value))))


(defn create-args
  []
  "creates queues,offers and puts it in map"
    (let[
       in-queue (ref (worker/create-queue))
       out-queue (ref (worker/create-queue))
       unique-offers (ref {})
       all-offers (ref {})
       args {:in-queue in-queue :out-queue out-queue :unique-offers unique-offers :all-offers all-offers}]
      args))

(defn create-empty-streams
  []
  "creates empty streams map"
  {:in nil :out nil :socket nil})

;Test only one min unique offer
(deftest test1
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer {:streams streams :offer "100"}]
    (offer/process-request1 offer args)
    (is-coll-size 1 @(:unique-offers args))
    (is-coll-size 1 @(:all-offers args))))

(test1)

;Adding two offers. The second one is new min unique offer
(deftest test2
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "90"}]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (is-coll-size 2 @(:unique-offers args))
    (is-coll-size 2 @(:all-offers args))
    (is-offer-counter 1 100.0 @(:all-offers args))
    (is-offer-counter 1 90.0 @(:all-offers args))
    (is-offer-min 90 @(:unique-offers args))))

(test2)

;Adding two offers with same values. There is no unique offer after adding
(deftest test3
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (is-coll-size 0 @(:unique-offers args))
    (is-coll-size 1 @(:all-offers args))
    (is-offer-counter 2 100.0 @(:all-offers args))))

(test3)

;Adding 5 offers with same values. There is no unique offer ofter adding
;and counter of value is 5.
(deftest test4
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}
       offer3 {:streams streams :offer "100"}
       offer4 {:streams streams :offer "100"}
       offer5 {:streams streams :offer "100"}]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (offer/process-request1 offer4 args)
    (offer/process-request1 offer5 args)
    (is-coll-size 0 @(:unique-offers args))
    (is-coll-size 1 @(:all-offers args))
    (is-offer-counter 5 100.0 @(:all-offers args))))

(test4)

;Adding 2 offers. The second one is great then the first.
;First offer is unique.
(deftest test5
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "120"}]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (is-coll-size 2 @(:unique-offers args))
    (is-coll-size 2 @(:all-offers args))
    (is-offer-min 100 @(:unique-offers args))
    (is-offer-counter 1 100.0 @(:all-offers args))
    (is-offer-counter 1 120.0 @(:all-offers args))))

(test5)



;Adding 2 offers. The second one is lower then the first.
;Second offer is unique.
(deftest test6
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "90"}]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (is-coll-size 2 @(:unique-offers args))
    (is-coll-size 2 @(:all-offers args))
    (is-offer-min 90 @(:unique-offers args))
    (is-offer-counter 1 100.0 @(:all-offers args))
    (is-offer-counter 1 90.0 @(:all-offers args))))

(test6)


;Adding 3 offers. Every offer is lower than the previous one.
(deftest test7
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "90"}
       offer3 {:streams streams :offer "80"}
       ]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (is-coll-size 3 @(:unique-offers args))
    (is-coll-size 3 @(:all-offers args))
    (is-offer-min 80 @(:unique-offers args))
    (is-offer-counter 1 100.0 @(:all-offers args))
    (is-offer-counter 1 90.0 @(:all-offers args))
    (is-offer-counter 1 80.0 @(:all-offers args))))

(test7)


;Adding 3 offers. First and second have same value and third has lower value.
;The third offer is unique.
(deftest test8
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}
       offer3 {:streams streams :offer "80"}
       ]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (is-coll-size 1 @(:unique-offers args))
    (is-coll-size 2 @(:all-offers args))
    (is-offer-min 80 @(:unique-offers args))
    (is-offer-counter 2 100.0 @(:all-offers args))
    (is-offer-counter 1 80.0 @(:all-offers args))))

(test8)


;Adding 3 offers. First and second have same value and third has grater value.
;The third offer is unique.
(deftest test8
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}
       offer3 {:streams streams :offer "110"}
       ]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (is-coll-size 1 @(:unique-offers args))
    (is-coll-size 2 @(:all-offers args))
    (is-offer-min 110 @(:unique-offers args))
    (is-offer-counter 2 100.0 @(:all-offers args))
    (is-offer-counter 1 110.0 @(:all-offers args))))

(test8)


;Adding 5 offers. Two pairs have same value and one offer is unique.
;The unique value is between values of two pairs.
(deftest test9
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}
       offer3 {:streams streams :offer "110"}
       offer4 {:streams streams :offer "120"}
       offer5 {:streams streams :offer "120"}
       ]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (offer/process-request1 offer4 args)
    (offer/process-request1 offer5 args)
    (is-coll-size 1 @(:unique-offers args))
    (is-coll-size 3 @(:all-offers args))
    (is-offer-min 110 @(:unique-offers args))
    (is-offer-counter 2 100.0 @(:all-offers args))
    (is-offer-counter 2 120.0 @(:all-offers args))
    (is-offer-counter 1 110.0 @(:all-offers args))))

(test9)


;Adding 5 offers. Two pairs have same value and one offer is unique.
;The unique value is lower then values of two pairs.
(deftest test10
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}
       offer3 {:streams streams :offer "80"}
       offer4 {:streams streams :offer "120"}
       offer5 {:streams streams :offer "120"}
       ]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (offer/process-request1 offer4 args)
    (offer/process-request1 offer5 args)
    (is-coll-size 1 @(:unique-offers args))
    (is-coll-size 3 @(:all-offers args))
    (is-offer-min 80 @(:unique-offers args))
    (is-offer-counter 2 100.0 @(:all-offers args))
    (is-offer-counter 2 120.0 @(:all-offers args))
    (is-offer-counter 1 80.0 @(:all-offers args))))

(test10)


;Adding 5 offers. Two pairs have same value and one offer is unique.
;The unique value is grater then values of two pairs.
(deftest test11
  (let[
       args (create-args)
       streams (create-empty-streams)
       offer1 {:streams streams :offer "100"}
       offer2 {:streams streams :offer "100"}
       offer3 {:streams streams :offer "140"}
       offer4 {:streams streams :offer "120"}
       offer5 {:streams streams :offer "120"}
       ]
    (offer/process-request1 offer1 args)
    (offer/process-request1 offer2 args)
    (offer/process-request1 offer3 args)
    (offer/process-request1 offer4 args)
    (offer/process-request1 offer5 args)
    (is-coll-size 1 @(:unique-offers args))
    (is-coll-size 3 @(:all-offers args))
    (is-offer-min 140 @(:unique-offers args))
    (is-offer-counter 2 100.0 @(:all-offers args))
    (is-offer-counter 2 120.0 @(:all-offers args))
    (is-offer-counter 1 140.0 @(:all-offers args))))

(test11)








     